#include "PlayState.h"

vector<GameObject*> ListObjects;
Mario* _mario = NULL;

PlayState::PlayState(Resources* res, bool newgame)
:State(res)
{
	_mario = NULL;
	_resources = res;
	_TreeUpdate = NULL;
	_TreeRender = NULL;
	_background = _resources->_bgGame->GetImage();
	if (newgame == true)
	{
		LoadNextLevel();
	}
	else
	{
		_TreeUpdate = new QNode();
		_TreeRender = new QNode();
		Method::BuildTree("Resources\\Map\\mapSave.txt", _resources, _TreeUpdate, _TreeRender, _mario);

		_viewport = new Viewport(0, 600, 800, 600);
	}

	_info = new Info(_resources);

	_count_time = 0;
}

PlayState::~PlayState()
{
	
}

void PlayState::Update(float time)
{
	if (GAME_WORLD >= 5) return;

	// Update Time
	if (_count_time < 60) _count_time++;
	else
	{
		GAME_TIME--;
		_count_time = 0;
	}

	// Update Viewport
	if (_mario->PosX() > 400 && GAME_WORLD > 0)
		_viewport->SetPosX(_mario->PosX() - 400);
	
	// Get object in viewport
	Method::GetObjectInViewport(_viewport->Rect(), _TreeUpdate, _list, _listStatic);

	// Update Mario
	if (_mario != NULL)
		_mario->Update(time, _TreeUpdate);

	if (_mario->PosX() > 780 && GAME_WORLD == 0)
		_mario->SetPosX(780);


	//_______________________________________________________________________
	int n = _list.size();
	// Update Dynamic Objects
	for each (GameObject* o in _list)
	{
		o->Update(time, _TreeUpdate);
	}

	//______________________________________________________________________
	// Update Static Objects
	n = _listStatic.size();
	for each (GameObject* o in _listStatic)
	{
		o->Update(time, _TreeUpdate);
	}

	//______________________________________________________________________

	// Update Objects Mushroom, Star, Bullet...
	for (int i = 0; i < ListObjects.size(); i++)
	{
		ListObjects[i]->Update(time, _TreeUpdate);
		
		if (ListObjects[i]->GetIsAlive() == false)
		{
			GameObject* o = ListObjects[i];
			ListObjects.erase(ListObjects.begin() + i);
			delete o;
		}

	}

	// Clear List
	_list.clear();
	_listStatic.clear();

	//=========================================================================
	if (_mario->GetIsAlive() == false)
	{
		GAME_LIVE--;

		if (GAME_LIVE == -1)
			_resources->_audio->PlaySoundA(_resources->GameOver);
		
		if (GAME_LIVE >= 0)
		{
			delete _mario;
			_mario = NULL;
			LoadNextLevel();
		}
	}

	if (_mario->GetIsWin() == true)
	{
		GAME_WORLD++;
		_mario->SetIsWin(false);
		_mario->SetIsChangeMap(false);
		_mario->SetAy(GRAVITY);
		LoadNextLevel();

	}
}

void PlayState::ProcessInput(Input* input)
{
	if (GAME_WORLD < 5)
		_mario->ProcessInput(input);

	if (input->KeyDown(DIK_ESCAPE))
	{
		_next_state = ST_Menu;
		_close = true;
	}
}

void PlayState::Render(LPD3DXSPRITE spriteHandler)
{
	_resources->_pd3ddv->StretchRect(_background, NULL, _resources->_back_buffer, NULL, D3DTEXF_NONE);
	
	if (GAME_WORLD >= 5) return;

	Method::GetObjectInViewport(_viewport->Rect(), _TreeRender, _list, _list);

	// Sort listObject
	std::sort(_list.begin(), _list.end(), Method::MaxDepth);

	int n = _list.size();

	// Test
	if (n > 35)
	{
		n++;
		n--;
	}

	GameObject* pipe = NULL;
	for each (GameObject* o in _list)
	{
		if (o->ID() == ID::ID_PipeSpecial)
		{
			pipe = o;
			continue;
		}
		
		o->Render(spriteHandler, _viewport);
	}
	
	_list.clear();

	// Render Objects Mushroom, Star, Bullet...
	n = ListObjects.size();
	for (int i = 0; i < n; i++)
	{
		ListObjects[i]->Render(spriteHandler, _viewport);
	}

	// Render Mario
	_mario->Render(spriteHandler, _viewport);

	// Code bua :)
	if (pipe != NULL)
		pipe->Render(spriteHandler, _viewport);

	_info->Render(spriteHandler, _viewport);
}

void PlayState::Release()
{
	// Save game
	if (GAME_WORLD > 0)
		Method::SaveTree("Resources\\Map\\mapSave.txt", _TreeUpdate, _TreeRender, _mario);

	delete _mario;
	delete _viewport;
	delete _TreeRender;
	delete _TreeUpdate;
	delete _info;

	// Delete Objects Mushroom, Star, Bullet...
	int n = ListObjects.size();
	for (int i = 0; i < n; i++)
	{
		delete ListObjects[i];
	}
	
	ListObjects.clear();
}

void PlayState::LoadNextLevel()
{
	// Delete something

	if(_TreeUpdate != NULL) delete _TreeUpdate;
	if(_TreeRender != NULL) delete _TreeRender;
	if(_viewport != NULL) delete _viewport;

	// Reaload game win next level
	_TreeUpdate = new QNode();
	_TreeRender = new QNode();

	// Create new path with _level
	string path = "Resources\\Map\\map";
	ostringstream Convert;
	Convert << (GAME_WORLD);
	path.insert(path.length(), Convert.str());
	path.insert(path.length(), ".txt");

	Method::BuildTree(path, _resources, _TreeUpdate, _TreeRender, _mario);

	_viewport = new Viewport(0, 600, 800, 600);

	if (GAME_WORLD < 2)
		_background = _resources->_bgGame->GetImage();
	else if (GAME_WORLD < 5)
		_background = _resources->_bgGame2->GetImage();
	else
	{
		_background = _resources->_bgGame3->GetImage();
	}

	GAME_TIME = 300;
}